import com.the8thfold.anton.users.Role
import com.the8thfold.anton.users.Roles
import com.the8thfold.anton.users.User
import com.the8thfold.anton.users.UserRole
import grails.plugin.multitenant.core.util.TenantUtils
import com.the8thfold.anton.utils.QuickId
import com.the8thfold.anton.ant.AntScript
import com.the8thfold.anton.ant.AntJob
import com.the8thfold.anton.ant.AntJobPropertyValue
import com.the8thfold.anton.ant.AntJobRunResults
import com.the8thfold.anton.ant.AntJobStatus
import com.the8thfold.anton.ant.AntJobTarget
import com.the8thfold.anton.ant.JobStatus
import com.the8thfold.anton.settings.Configuration
import com.the8thfold.anton.settings.ConfigurationItem
import com.the8thfold.anton.ant.AntJobUser

class BootStrap {

    def springSecurityService
    def mailService
    def settingsService

    def init = { servletContext ->
        TenantUtils.doWithTenant(1, {

            setupConfig();
            setupRolesAndUsers();
            setupInitialData();

        })
    }
    def setupConfig = {
        setupConfigGeneral();
        setupConfigMail();
    }

    def setupConfigGeneral = {
        Configuration config = new Configuration(name: 'General');
        config.save(flush:true)

        String outputPath = "c:/work/workspace/anton/output-path"

        String scriptsFolderName = "scripts"
        String jobsFolderName = "jobs"
        String resultsFolderName = "results"


        config.addToConfigurationItems(new ConfigurationItem(key: "outputPath",value: outputPath))
        config.addToConfigurationItems(new ConfigurationItem(key: "scriptsFolderName",value: scriptsFolderName))
        config.addToConfigurationItems(new ConfigurationItem(key: "jobsFolderName",value: jobsFolderName))
        config.addToConfigurationItems(new ConfigurationItem(key: "resultsFolderName",value: resultsFolderName))
    }

    def setupConfigMail = {
        Configuration config = new Configuration(name: 'Mail Server');
        config.save(flush:true)

        String serverHost = "smtp.gmail.com"
        String serverPort = "465"
        String userName = ""
        String password = ""
        String mailSmtpAuth = "true"
        String mailSmtpSocketFactoryPort = "465"
        String mailSmtpSocketFactoryClass = "javax.net.ssl.SSLSocketFactory"
        String mailSmtpSocketFactoryFallback = "false"


        config.addToConfigurationItems(new ConfigurationItem(key: "host",value: serverHost))
        config.addToConfigurationItems(new ConfigurationItem(key: "port",value: serverPort))
        config.addToConfigurationItems(new ConfigurationItem(key: "userName",value: userName))
        config.addToConfigurationItems(new ConfigurationItem(key: "password",value: password))
        config.addToConfigurationItems(new ConfigurationItem(key: "mail.smtp.auth",value: mailSmtpAuth))
        config.addToConfigurationItems(new ConfigurationItem(key: "mail.smtp.socketFactory.port",value: mailSmtpSocketFactoryPort))
        config.addToConfigurationItems(new ConfigurationItem(key: "mail.smtp.socketFactory.class",value: mailSmtpSocketFactoryClass))
        config.addToConfigurationItems(new ConfigurationItem(key: "mail.smtp.socketFactory.fallback",value: mailSmtpSocketFactoryFallback))

    }

    def setupRolesAndUsers = {
        def adminRole = new Role(authority: Roles.ROLE_ADMIN.toString()).save(flush: true)
        def scriptRole = new Role(authority: Roles.ROLE_SCRIPT_ADMIN.toString()).save(flush: true)
        def jobAdminRole = new Role(authority: Roles.ROLE_JOB_ADMIN.toString()).save(flush: true)
        def jobRunRole = new Role(authority: Roles.ROLE_JOB_RUN.toString()).save(flush: true)
        def resultAdminRole = new Role(authority: Roles.ROLE_RESULTS_ADMIN.toString()).save(flush: true)
        def resultViewRole = new Role(authority: Roles.ROLE_RESULTS_VIEW.toString()).save(flush: true)

        // Admin user
        String adminPassword = springSecurityService.encodePassword('admin')
        def adminUser = new User(firstName: 'Admin', lastName: 'User', userId: QuickId.newId,
                userTenantId: 1, username: 'admin', enabled: true, password: adminPassword)
        adminUser.save(flush: true, failOnError: true)

        UserRole.create adminUser, adminRole, true

        // Demo user
        String demoPassword = springSecurityService.encodePassword('demo')
        def demoUser = new User(firstName: 'Demo', lastName: 'User', userId: QuickId.newId,
                userTenantId: 1, username: 'demo', enabled: true, password: demoPassword)
        demoUser.save(flush: true, failOnError: true)

        UserRole.create demoUser, jobAdminRole, true
    }

    def setupInitialData = {
        AntScript script = new AntScript(
                scriptId: QuickId.newId,
                description: "Demo Script",
                scriptFilePath: "C:/work/workspace/anton/build.xml",
                createdBy: User.findByUsername("demo")
        ).save(flush: true, failOnError: true)

        /*AntScript script2 = new AntScript(
                scriptId: QuickId.newId,
                description: "DC Script",
                scriptFilePath: "C:/work/workspace/anton/build-beta-core.xml",
                createdBy: User.findByUsername("demo")
        ).save(flush: true, failOnError: true)*/

        AntJob job = new AntJob(
                jobId: QuickId.newId,
                name: "Deploy new version to Staging",
                description: "Update all wars and restart tomcats",
                createdBy: User.findByUsername("demo"),
                jobStatus: JobStatus.ACTIVE,
                script: script
        ).save(flush: true, failOnError: true)

        AntJobPropertyValue jobPropertyValue = new AntJobPropertyValue(
                propertyId: QuickId.newId,
                name: "dist",
                value: "here",
                defaultValue: "default here",
                job: job
        ).save(flush: true, failOnError: true)

        job.addToPropertyValues(jobPropertyValue).save(flush: true, failOnError: true)

        AntJobTarget jobTarget = new AntJobTarget(
                targetId: QuickId.newId,
                ordinal: 1,
                name: "dist",
                description: "",
                job: job
        ).save(flush: true, failOnError: true)

        job.addToTargets(jobTarget).save(flush: true, failOnError: true)
        def now = new Date();
        AntJobRunResults jobRunResults = new AntJobRunResults(
                runResultsId: QuickId.newId,
                name: "$job.name [$now]",
                createdBy: User.findByUsername("demo"),
                job: job,
                status: AntJobStatus.CREATED
        ).save(flush: true, failOnError: true)

        job.addToRunResults(jobRunResults).save(flush: true, failOnError: true)

        job.addToUsers(new AntJobUser(job: job, user: User.findByUsername("demo")))
    }

    def destroy = {
    }
}
